#include "string.h"
#include "eth_driver.h"
#include "modbus_master.h"
#include "tcphandle.h"
#include "usart.h"
#include "ch32v20x_it.h"
#include "cache.h"

/*�������*/

uint8_t functionCode = 3;
uint16_t startAddress = 0;
uint16_t quantity = 10;

uint8_t last_functionCode = 3;
uint16_t last_startAddress = 0;
uint16_t last_quantity = 10;
uint16_t trans_id_from_poll = 0;
    uint8_t state ;
    uint16_t data ;

uint32_t cacheLength = 0; // tcp缓存区发送长度
u8 connect_success = 0;

// 新的缓存区
uint8_t cache_buffer[TCP_BUFFER_SIZE]; // 声明新的变量 cache_buffer

//modbus_rtu_to_tcp的改版
void Cache_RTU_To_TCP(u8 socketId) {  //转TCP
    trans_id++;
    if (Rxfinish==0) {   //没收到不执行操作
        return;
    } 
    for(int i =0;i<256;i++)
    {
        tcpSendBuffer[i] = 5;
    }
    uint32_t tcpSendLength = 0; // 重置发送长度
    /*test */


    u8 Data_length = 0;
    Data_length = RxCnt -2;
    //trans_id++;
    // RxCnt--;
    // RxCnt--;
    tcpSendBuffer[tcpSendLength++] = ((trans_id_from_poll )>>8)&0xFF; // Transaction Identifier 高字节
    tcpSendBuffer[tcpSendLength++] = (trans_id_from_poll) & 0xFF; // Transaction Identifier 低字节
    tcpSendBuffer[tcpSendLength++] = 0x00; // Protocol Identifier 高字节
    tcpSendBuffer[tcpSendLength++] = 0x00; // Protocol Identifier 低字节
    tcpSendBuffer[tcpSendLength++] = (Data_length>> 8) & 0xFF; // Length 高字节
    tcpSendBuffer[tcpSendLength++] = Data_length & 0xFF; // Length 低字节
    tcpSendBuffer[tcpSendLength++] = RxBuffer[0]; // 从站地址

    // 复制 RTU 数据到 TCP 数据包中
    
    for (int i = 1; i < RxCnt-2; i++) {  //
        tcpSendBuffer[tcpSendLength++] = RxBuffer[i];       ///rxbuffer???????????
        
    }

        uint32_t len = tcpSendLength;
        WCHNET_SocketSend(socketId, tcpSendBuffer, &len);  //发送函数 发送tcp报文
       // test_key = 1;
       Delay_Ms(1);  // 增加发送后的延时
    Reset_usart(); // RTU串口 重置计数并且清空缓存区 
    
}

//tcp缓存区
void Save_RTU_To_TCP(void)
{
    if (Rxfinish == 1) {
        cacheLength = 0;
        u16 Data_length = RxCnt - 2;  // 去掉CRC

        // 事务号直接用上位机给的
        cache_buffer[cacheLength++] = ((trans_id_from_poll + 1) >> 8) & 0xFF;
        cache_buffer[cacheLength++] = (trans_id_from_poll + 1) & 0xFF;

        cache_buffer[cacheLength++] = 0x00; // Protocol ID 高
        cache_buffer[cacheLength++] = 0x00; // Protocol ID 低
        cache_buffer[cacheLength++] = (Data_length >> 8) & 0xFF;
        cache_buffer[cacheLength++] = Data_length & 0xFF;
        cache_buffer[cacheLength++] = RxBuffer[0]; // Unit ID

        // RTU数据向TCP缓存区存储
        for (int i = 1; i < RxCnt - 2; i++) {
            cache_buffer[cacheLength++] = RxBuffer[i];
        }

        Reset_usart();
    }
}

// 解析并且获取上位机配置数据
void Handle_Host_TcpData(u8 *tcpBuffer, u32 length)
{
    if (length < 12) return;  // 至少有 MBAP(7) + 功能码(1) + 起始地址(2) + 数量(2)

    trans_id_from_poll = (tcpBuffer[0] << 8) | tcpBuffer[1]; // 保存事务号
    functionCode = tcpBuffer[7];
    startAddress = (tcpBuffer[8] << 8) | tcpBuffer[9];
    quantity     = (tcpBuffer[10] << 8) | tcpBuffer[11];
    state = tcpBuffer[10];  //05功能码状态存储
    data =(tcpBuffer[10]<<8) | tcpBuffer[11];
    

    //memset(tcpBuffer, 0, TCP_BUFFER_SIZE);
}

// 处理上位机命令，并把值返回给上位机
void Handle_Host_Cmd(u8 socketId)
{
    
    receivedLength = sizeof(tcpBuffer);
    u8 result = WCHNET_SocketRecv(socketId, tcpBuffer, &receivedLength);

    if (result == WCHNET_ERR_SUCCESS) {
        Handle_Host_TcpData(tcpBuffer, receivedLength);
        connect_success = 1;

           

        if(functionCode>4)
        {
            
            
            switch (functionCode) 
            {
                case 5:
                    Modbus_RTU_05H(startAddress, state);
                    break;
                case 6:
                    Modbus_RTU_06h(startAddress,data);
                    break;
                case 15:
                    Modbus_RTU_15H(startAddress,quantity);
                    break;
                case 16:
                    Modbus_RTU_16h(startAddress,quantity);
                    break;
                default:
                    // printf("Unknown function code: %d\r\n", functionCode);
                    break;
            }

            Delay_Ms(80);  // 在增加延时

            
            Cache_RTU_To_TCP(socketId);
            


            functionCode = last_functionCode;
            quantity = last_quantity;
            startAddress = last_startAddress;
        

        }
        

        else if(functionCode<=4)
        {
            Modbus_RTU_03H(startAddress, quantity, functionCode);



            //检查配置是否与之前一致，一致则直接发送
            if (last_functionCode == functionCode && last_quantity == quantity && last_startAddress == startAddress) {
            // 直接回缓存
            //Modbus_RTU_03H(startAddress, quantity, functionCode);
            u32 len = cacheLength;
             
            //优化
            cache_buffer[cacheLength++] = ((trans_id_from_poll + 1) >> 8) & 0xFF;
            cache_buffer[cacheLength++] = (trans_id_from_poll + 1) & 0xFF;
            WCHNET_SocketSend(socketId, cache_buffer, &len);
            Reset_usart();
            } 


            //不一致则重走一遍流程
            else { 
            // 新请求 → 转发到RTU
            Modbus_RTU_03H(startAddress, quantity, functionCode);


            Save_RTU_To_TCP();  // 使用上位机事务号
            
            u32 len = cacheLength;
            WCHNET_SocketSend(socketId, cache_buffer, &len);

            last_functionCode = functionCode;
            last_quantity     = quantity;
            last_startAddress = startAddress;
            }
           
        }
    memset(tcpBuffer,0,TCP_BUFFER_SIZE); //清空缓存区
    }
    
}   


// 轮询时候使用
void cache_manage(u8 lastConnectedSocketId)
{

    // 监听是否接收到上位机TCP指令,取得tcp重要指令于变量中，并且直接发送缓存,如果无指令则直接跳过
    
    // 默认发送03h 10个寄存器和寄存器起始地址0


    if(connect_success == 0) //没连上网络则持续轮询
    {
        Modbus_RTU_03H(startAddress, quantity, functionCode);
        
    }
    // 顺序交换是因为万一
    // 串口缓存区的 RTU转TCP 并且更新缓存 cache_buffer  
    Save_RTU_To_TCP();
    connect_success = 0;
    Handle_Host_Cmd(lastConnectedSocketId);
    Delay_Ms(1);  // 在每次循环结束时增加延时
}